import * as BABYLON from "@babylonjs/core/Legacy/legacy";
import { GLTFFileLoader } from "@babylonjs/loaders/glTF";
// import store from "@/stores";
import Lodash from "lodash";

export default class MyScenes {
  _canvas: HTMLCanvasElement; //画布
  _engine: BABYLON.Engine; //引擎
  _scene: BABYLON.Scene | undefined; //场景
  _camera: BABYLON.FreeCamera | undefined; //相机
  _light: BABYLON.HemisphericLight | undefined; //灯光
  // _store = store;

  constructor(canvasElement: HTMLCanvasElement) {
    // Create canvas and engine.
    this._canvas = canvasElement;
    // console.info("状态管理", this._store);
    this._engine = new BABYLON.Engine(this._canvas, true);
  }

  createScene() {
    // Create a basic BJS Scene object.
    this._scene = new BABYLON.Scene(this._engine);

    // Create a FreeCamera, and set its position to (x:0, y:5, z:-10).
    this._camera = new BABYLON.FreeCamera(
      "camera1",
      new BABYLON.Vector3(0, 250, 0),
      this._scene
    );
    // this._camera.maxZ = 1000;

    // // Target the camera to scene origin.
    // this._camera.setTarget(BABYLON.Vector3.Zero());

    // Attach the camera to the canvas.
    this._camera.attachControl(this._canvas, false);
    this._camera.onViewMatrixChangedObservable.add(() => {
      console.log("视图矩阵");
      if (this._camera) console.log("视图矩阵", this._camera.getActiveMeshes());
    });

    // Create a basic light, aiming 0,1,0 - meaning, to the sky.
    this._light = new BABYLON.HemisphericLight(
      "light1",
      new BABYLON.Vector3(0, 1, 0),
      this._scene
    );
    this._light.intensity = 1;
    console.log(BABYLON.SceneLoader);

    let num = 60; //60个地板
    let groundArry = []; //地板数组
    for (let i = 0; i < num / 3; i++) {
      for (let j = 0; j < num / 3; j++) {
        let ground = BABYLON.Mesh.CreateGround(`ground${i}-${j}`, 500, 500, 2);
        ground.metadata = {
          layerLoad: [
            //判断哪层被加载
            false,
            false,
            false,
          ],
          num: (i + 1) * (j + 1),
        };
        groundArry.push(ground);
        ground.position = new BABYLON.Vector3(500 * i, 0, 500 * j);
      }
    }
    this._camera.position = new BABYLON.Vector3(
      (500 * num) / 3 / 2,
      1000,
      (500 * num) / 3 / 2
    );
    this._camera.setTarget(
      new BABYLON.Vector3((500 * num) / 3 / 2, 0, (500 * num) / 3 / 2)
    );

    groundArry.forEach((item) => {
      item.addLODLevel(
        1500,
        BABYLON.Mesh.CreateGround(`ground-default`, 500, 500, 2)
      );

      item.onLODLevelSelection = (distance, mesh, selectLeven) => {
        // console.log("LOD_MESH", mesh);
        if (distance < 2500 && !mesh.metadata.layerLoad[0]) {
          mesh.metadata.layerLoad[0] = true;
          // console.log("距离变化", distance, mesh, selectLeven);

          BABYLON.SceneLoader.ImportMesh(
            "",
            // `${process.env.BASE_URL}mesh/cube_pice/`,
            // `${mesh.metadata.num}.babylon`,
            `${process.env.PUBLIC_URL}mesh/test/`,
            "groud.babylon",
            this._scene,
            (data) => {
              let groud = new BABYLON.Mesh(`城市分片地面${item.name}`);
              data.forEach((child) => {
                child.parent = groud;
              });
              groud.parent = mesh;
              groud.scaling = new BABYLON.Vector3(10, 1, 10);
              // setTimeout(() => {
              //   city.dispose();
              // }, 10000);

              console.log("场景模型", data);
            }
          );
        } else if (distance < 1000 && !mesh.metadata.layerLoad[1]) {
          mesh.metadata.layerLoad[1] = true;
          // console.log("距离变化", distance, mesh, selectLeven);

          BABYLON.SceneLoader.ImportMesh(
            "",
            // `${process.env.BASE_URL}mesh/cube_pice/`,
            // `${mesh.metadata.num}.babylon`,
            `${process.env.PUBLIC_URL}mesh/test/`,
            "road.babylon",
            this._scene,
            (data) => {
              let road = new BABYLON.Mesh(`城市分片道路${item.name}`);
              data.forEach((child) => {
                child.parent = road;
              });
              road.parent = mesh;
              road.scaling = new BABYLON.Vector3(10, 1, 10);
              // setTimeout(() => {
              //   city.dispose();
              // }, 10000);

              console.log("场景模型", data);
            }
          );
        } else if (distance < 500 && !mesh.metadata.layerLoad[2]) {
          mesh.metadata.layerLoad[2] = true;
          // console.log("距离变化", distance, mesh, selectLeven);

          BABYLON.SceneLoader.ImportMesh(
            "",
            // `${process.env.BASE_URL}mesh/cube_pice/`,
            // `${mesh.metadata.num}.babylon`,
            `${process.env.PUBLIC_URL}mesh/test/`,
            "room.babylon",
            this._scene,
            (data) => {
              let room = new BABYLON.Mesh(`城市分片房屋${item.name}`);
              data.forEach((child) => {
                child.parent = room;
              });
              room.parent = mesh;
              room.scaling = new BABYLON.Vector3(10, 1, 10);
              // setTimeout(() => {
              //   city.dispose();
              // }, 10000);

              console.log("场景模型", data);
            }
          );
        } else if (distance > 3000 && mesh.metadata.layerLoad[0]) {
          mesh.metadata.layerLoad[0] = false;
          let city: BABYLON.AbstractMesh;
          mesh.getChildMeshes().forEach((item) => {
            if (item.name.indexOf("城市分片地面") != -1) {
              city = item;
            }
          });
          console.log("回收模型", mesh.getChildMeshes());

          setTimeout(() => {
            // 不知道到为啥这里回收要写定时器 估计是边render边回收的问题
            city.getChildMeshes().forEach((item) => {
              item.dispose(true, true);
            });
            city.dispose(true, true);
          }, 100);
        } else if (distance > 2000 && mesh.metadata.layerLoad[1]) {
          mesh.metadata.layerLoad[1] = false;
          let road: BABYLON.AbstractMesh;
          mesh.getChildMeshes().forEach((item) => {
            if (item.name.indexOf("城市分片道路") != -1) {
              road = item;
            }
          });
          console.log("回收模型", mesh.getChildMeshes());

          setTimeout(() => {
            // 不知道到为啥这里回收要写定时器 估计是边render边回收的问题
            road.getChildMeshes().forEach((item) => {
              item.dispose(true, true);
            });
            road.dispose(true, true);
          }, 100);
        } else if (distance > 1000 && mesh.metadata.layerLoad[2]) {
          mesh.metadata.layerLoad[2] = false;
          let room: BABYLON.AbstractMesh;
          mesh.getChildMeshes().forEach((item) => {
            if (item.name.indexOf("城市分片房屋") != -1) {
              room = item;
            }
          });
          console.log("回收模型", mesh.getChildMeshes());

          setTimeout(() => {
            // 不知道到为啥这里回收要写定时器 估计是边render边回收的问题
            room.getChildMeshes().forEach((item) => {
              item.dispose(true, true);
            });
            room.dispose(true, true);
          }, 100);
        }
        // else if (distance > 2000 && mesh.metadata.isLoadDetail) {
        //   mesh.metadata.layerLoad[1] = false;
        //   let city = mesh.getChildMeshes()[0];
        //   console.log("回收模型", city);

        //   setTimeout(() => {
        //     // 不知道到为啥这里回收要写定时器 估计是边render边回收的问题
        //     city.getChildMeshes().forEach((item) => {
        //       item.dispose(true, true);
        //     });
        //     city.dispose(true, true);
        //   }, 100);
        // }
      };
    });

    // Playground needs to return at least an empty scene and default camera
    // GLTFFileLoader.IncrementalLoading = true;
    // Async call
    // BABYLON.SceneLoader.RegisterPlugin(new GLTFFileLoader());
    // BABYLON.SceneLoader.Append(
    //   // "",
    //   `${process.env.BASE_URL}mesh/city/`,
    //   "daocu100.babylon",
    //   this._scene,
    //   (data) => {
    //     console.log("场景模型", data);

    //     // if (this._camera) {
    //     //   this._camera.attachControl(this._canvas, true);
    //     //   let knot00 = BABYLON.Mesh.CreateTorusKnot(
    //     //     "knot0",
    //     //     0.5,
    //     //     0.2,
    //     //     128,
    //     //     64,
    //     //     2,
    //     //     3,
    //     //     this._scene
    //     //   );
    //     //   let ground = BABYLON.Mesh.CreateGround("ground", 10, 10, 2);
    //     //   knot00.addLODLevel(10, null);
    //     //   knot00.addLODLevel(20, ground);
    //     //   knot00.onLODLevelSelection = (distance, mesh, selectLeven) => {
    //     //     // console.log("距离变化", distance, mesh, selectLeven);
    //     //   };
    //     //   let mesh = data[0] as BABYLON.Mesh;
    //     //   mesh.addLODLevel(100, null);
    //     //   mesh.onLODLevelSelection = (distance, mesh, selectLeven) => {
    //     //     console.log("距离变化", distance, mesh, selectLeven);
    //     //     if (distance > 100) {
    //     //       console.log("加载");
    //     //     }
    //     //   };
    //     //   // console.log(new BABYLON.Mesh("6", this._scene, data[0]));

    //     //   // console.log(data[0].getLOD(this._camera));
    //     // }
    //   }
    // );

    // BABYLON.SceneLoader.Append(
    //   `${process.env.BASE_URL}mesh/city/`,
    //   "222.incremental.babylon",
    //   this._scene,
    //   () => {
    //     if (this._camera) this._camera.attachControl(this._canvas, true);
    //   }
    // );

    // Create a built-in "sphere" shape with 16 segments and diameter of 2.
    // let sphere = BABYLON.MeshBuilder.CreateSphere(
    //   "sphere1",
    //   { segments: 16, diameter: 2 },
    //   this._scene
    // );

    // // Move the sphere upward 1/2 of its height.
    // sphere.position.y = 1;

    // // Create a built-in "ground" shape.
    // let ground = BABYLON.MeshBuilder.CreateGround(
    //   "ground1",
    //   { width: 6, height: 6, subdivisions: 2 },
    //   this._scene
    // );
  }

  doRender() {
    // Run the render loop.
    this._engine.runRenderLoop(() => {
      if (this._scene) {
        this._scene.render();
      }
    });

    // The canvas/window resize event handler.
    window.addEventListener("resize", () => {
      this._engine.resize();
    });
  }
}
